//------------------------------------------------------------------------------
// Copyright (c) 2007 Ste Brennan (dnaide.com)
// Licensed under the MIT (MIT-LICENSE.txt)
//------------------------------------------------------------------------------
using System;
using System.Globalization;

namespace DNAide.Core
{
	public static partial class CastAide
	{

		/// <summary>
		/// Returns an object of type T
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="value">Value to cast</param>
		/// <returns>Type T</returns>
		/// <remarks>
		/// <para>
		/// Will return default value of T if cast fails.
		/// </para>
		/// <para>
		/// Uses CultureInfo.CurrentCulture.
		/// </para>
		/// </remarks>
		public static T As<T>(object value)
		{
			return As(value, default(T), CultureInfo.CurrentCulture);
		}


		/// <summary>
		/// Returns an object of type T
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="value">Value to cast</param>
		/// <param name="defaultValue">Value returned if cast fails</param>
		/// <returns>Type T</returns>
		/// <remarks>
		/// <para>
		/// Uses CultureInfo.CurrentCulture.
		/// </para>
		/// </remarks>
		public static T As<T>(object value, T defaultValue)
		{
			return As(value, defaultValue, CultureInfo.CurrentCulture);
		}


		/// <summary>
		/// Returns an object of type T
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="value">Value to cast</param>
		/// <param name="provider">Instance of IFormatProvider</param>
		/// <returns>Type T</returns>
		/// <remarks>
		/// <para>
		/// Will return default value of T if cast fails.
		/// </para>
		/// </remarks>
		public static T As<T>(object value, IFormatProvider provider)
		{
			return As(value, default(T), CultureInfo.CurrentCulture);
		}


		/// <summary>
		/// 
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="value"></param>
		/// <param name="defaultValue"></param>
		/// <param name="provider"></param>
		/// <returns></returns>
		public static T As<T>(Object value, T defaultValue, IFormatProvider provider)
		{
			if (value == null || value == System.DBNull.Value)
				return defaultValue;

			if (provider == null)
				provider = CultureInfo.CurrentCulture;

			T retval;

			try
			{
				retval = (T)Convert.ChangeType(value, Type.GetTypeCode(typeof(T)), provider);
			}
			catch (InvalidCastException)
			{
				retval = defaultValue;
			}
			catch (FormatException)
			{
				retval = defaultValue;
			}

			return retval;
		}


		/// <summary>
		/// Returns an object of type T using invariant culture
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="value">Value to cast</param>
		/// <returns>Type T</returns>
		/// <remarks>
		/// <para>
		/// Will return default value of T if cast fails.
		/// </para>
		/// <para>
		/// Uses CultureInfo.InvariantCulture.
		/// </para>
		/// </remarks>
		public static T AsInvariant<T>(object value)
		{
			return As(value, default(T), CultureInfo.InvariantCulture);
		}


		/// <summary>
		/// Returns an object of type T using invariant culture
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="value">Value to cast</param>
		/// <param name="defaultValue">Value returned if cast fails</param>
		/// <returns>Type T</returns>
		/// <remarks>
		/// <para>
		/// Uses CultureInfo.InvariantCulture.
		/// </para>
		/// </remarks>
		public static T AsInvariant<T>(object value, T defaultValue)
		{
			return As(value, defaultValue, CultureInfo.InvariantCulture);
		}

	}
}
